<?php
/**
 * Classe de conexão com o mysql com funções pré-configuradas de inserção,
 * atualização, exclusão e selecao de dados
 *
 * @author Robert Diego de Jesus <beto.corujao@gmail.com>
 * @version 0.1
 * @package connectMysql.class
 * @subpackage connectMysql
 * @access public
 */
    class connectMysql{
        /**
         * Nome do banco de dados
         * @var string
         * @name $database
         * @access protected
         */
        protected  $database;
        /**
         * Nome do usuário no banco de dados selecionado
         * @var string
         * @name $user
         * @access protected
         */
        protected  $user;
        /**
         * Senha do usuário no banco de dados selecionado
         * @var string
         * @name $password
         * @access protected
         */
        protected  $password;
        /**
         * Host de acesso ao sistema
         * @var string
         * @name $host
         * @access protected
         */
        protected  $host;

        /**
         * Construtor da classe para inicializar os atributos protegidos $database, $user, $password e $host
         * @access public
         * @param string $Password Senha do usuario que acessa o banco (opcional). Se nao informado: NULL
         * @param string $User Nome do usuario que acessa o banco (opcional). Se nao informado: root
         * @param string $Host Host de acesso (opcional). Se nao informado: localhost
         *
         * <b>Exemplo de uso </b>
         * <code>
         *  <php
         *      require_once('connectMysql.class.php);
         *      $conexao = new connectMysql();
         *  </code>
         */
        public function  __construct($Password='', $User='root', $Host='localhost',$db='') {
            $this->host = $Host;
            $this->user = $User;
            $this->password = $Password;
            $this->database = $db;
            
            if(!empty ($this->database))
                $this->connection_db ($this->database);
        }


        // METODOS DE CONEXAO

        /**
         * Metodo que realiza a conexao com o banco de dados utilizando os atributos da classe
         * e as funcoes nativas do php: mysql_connect e mysql_selectdb
         * @name $connection_db
         * @access public
         * @param string $Database Nome do banco de dados a ser acessado
         * @abstract Modo de gravacao e recuperacao de dados no banco em utf8
         */
        public function connection_db($Database){
            if(!empty($Database)){
                $this->database = $Database;

                mysql_connect($this->host,  $this->user, $this->password);
                mysql_select_db($this->database) or die ('Não foi possível conectar. <br /> Erro '.mysql_errno().': '.  mysql_error());

                // gravacao de dados no banco de dados
                mysql_query("SET NAMES 'utf8'");
                mysql_query('SET caracter_set_connection=utf8');
                mysql_query('SET caracter_set_client=utf8');
                mysql_query('SET caracter_set_results=utf8');
            }
            else
                mysql_connect($this->host,  $this->user, $this->password);
        }

        /**
         * Metodo para fechar a conexao
         * @name desconnect_mysql()
         * @access public
         */
        public function desconnect_mysql(){
            mysql_close();
        }

        // SEGURANÇA NA INSERÇÃO DE DADOS

        /**
         * Método para previnir sql injection
         * @abstract Método usado nas funçoes que recebem dados do usuário para inibir tentativas de inserção de dados maliciosos no banco de dados.
         * @name anti_sql_injection
         * @param string $str valor a ser verificado
         * @access public
         * @return string
         *
         * <b>Obs.:</b> O Usuário poderá utilizar este método na função select_db, já que nela a SQL é montada livremente. <br>
         * Mais sobre o método
         * @link http://forum.imasters.com.br/topic/365340-funcao-anti-sql-injection/
         */
        public function anti_sql_injection($str) {
            
          if (!is_numeric($str)) {
                  $str = get_magic_quotes_gpc() ? stripslashes($str) : $str;
                 $str = function_exists('mysql_real_escape_string') ? mysql_real_escape_string($str) : mysql_escape_string($str);
             }
            return $str;
        }


        // METODOS DE SELECAO E EXIBICAO DE RESULTADOS

        /**
         * Metodo de selecao em banco de dados
         * @name select_db
         * @access protected
         * @return array
         * @param string $query String contendo as clausulas de selecao.
         * <br> <b>Exemplo:</b> parametro $query = "SELECT * FROM $database WHERE id = $id"
         */
        public function select($query){
            $result = mysql_query($query) 
                or die ('  Não foi possivel acessar os dados. <br /> Erro '. mysql_errno().': '.  mysql_error().'');
            return $result;
        }

        /**
         * Consulta unitaria dos campos de uma linha do banco de dados.
         * Método de seleção que retorna um array com os dados ['campo'] => valor.
         * O $where é obrigatório, pois o array criado irá apresentar informações de apenas um field.
         * @name select_field
         * @abstract Função semelhante a select_fields, porém retorna um array simples.
         * @access public
         * @return string
         * @param string $table Nome da tabela a ser consultada
         * @param array $array_dados Array contendo o nome dos fields a serem acessados (Ex: array('nome','email','telefone); ).
         * @param string $where Restrição de pesquisa (OBRIGATÓRIO). (Ex: "id = $id LIMIT 0,10").
         * 
         * Cria Um array com os dados recuperados do banco:
         * <code>
         *  Array(
         *         [Id] => 1
         *         [cod_cidade] => 11032100
         *         [nome_cidade] => APS Itu
         *        )
         * </code>
         * <b>Exemplo de uso: </b>
         * <code>
         *  $res = $con->select_field("SELECT * FROM usuario WHERE Id = $id_exig");
         *      <textarea id="txt_exigencia" name="txt_exigencia" cols="30" rows="10">
         *                 <?php echo $res['txt_exigencia'];?>
         *       </textarea>
         * </code>
         *
         * @see select_db
         * @see select_fields
         */
        public function select_field($query){
            $result = $this->select($query);

                $array_dados = array();
                $c = 0;
                $row = mysql_fetch_assoc($result);

                while($c < mysql_num_fields($result)){
                    $col = mysql_fetch_field($result,$c);
                    $array_dados[$col -> name] = $row[$col -> name];
                    ++$c;
                }

                return $array_dados;

        }

        /**        
         * Consulta Multiplos campos do banco de dados.
         * Cria um array bidimensional com o select = Array([indice]=> Array(dados))
         * @name select_fields
         * @access public
         * @return array
         * @param string $query consulta ao banco de dados
         *
         * Cria Um array bidimensional com os dados recuperados do banco:
         * <code>
         *  Array(
         *      [0] => Array(
         *         [Id_ol] => 1
         *         [cod_ol] => 11032100
         *         [nome_ol] => APS Itu
         *        )
         *       ) </code>
         * <br> utilize o foreach para selecionar.
         * <code>
         *   $res_acao = $con->select_db("SELECT Id, nome, origem, descricao FROM acao");
         *   $array_acao = $con->select_fields($res_acao);
         *
         *    <?php
         *         foreach($array_acao as $key){
         *                $id = $key['Id_acao'];
         *                $nome = $key['nome_acao'];
         *                $cod = $key['origem_acao'];
         *                $descricao = $key['descricao_acao'];
         *         }
         *   ?>
         * </code>
         */
        public function select_fields($query){
            
            $result = $this->select($query);
            
            //verifica o quantidade de campos no select
            $i = mysql_num_fields($result);

            $r = 0;
            $array_result = array();
            if($i){
                //    $row = matriz associativa do resultado
                while($row = mysql_fetch_assoc($result)){
                    $array_row = array();

                    $c = 0;
                    // enquanto $c < qtde de campos do select
                    while($c < mysql_num_fields($result)){
                       // $col = objetos com informacoes do campo entre 0 e $c
                        $col = mysql_fetch_field($result, $c);
                       // constroi array com o nome da coluna como array_row[name] = Robert
                       // ja que $row e o valor recebido na matriz associativa
                        $array_row[$col -> name] = $row[$col -> name];
                       ++$c;
                    }
                    // o array de resultado recebe o array com todos os campos
                    $array_result[$r] = $array_row;
                    $r++;
                }

                return $array_result;
            }
            else{
                die("Consulta Invalida.");
            }

        }

        /**
         * Retorna o número de linhas localizados em uma consulta
         * @abstract Retorna o número de linhas localizados em uma consulta
         * @name num_rows
         * @return int
         * @param array $result consulta sql do método select_db para contar
         * @see select_field
         *
         */
            public function num_rows($result){
            return mysql_num_rows($result);
        }
        
        /**
         * Retorna o id do último registro inserido no banco de dados
         * @abstract Retorna o id do último registro inserido no banco de dados
         * @name last_insert_id
         * @return int
         *
         */
        public function last_insert_id() {
            return mysql_insert_id();
        }


        // METODOS PARA INSERCAO DE DADOS

        /**
         * Método para inserção segura e dinamica no dados no banco
         * @abstract Permite inserir dados no banco de forma dinâmica.
         * @name insertion
         * @acess public
         * @return bool
         *
         * @param string $tabela Nome da tabela onde os dados serao gravado
         * @param array $values Array contendo os dados a serem cadastrado no banco.
         * @param date $date_insertion Data de inserção dos dados no banco baseando-se na data do banco através da funcao NOW()
         *
         *  O nome dos dadps deve ser igual ao da variavel no formulario.
         * <br> Exemplo: crie o array da seguinte forma:
         * <br> array('nome' => $nome, 'email' => $_POST['email'])
         */
       public function insertion($tabela, $values,  $date_insertion=''){

            // pegar campos da array
            // ([0]=>'nome',[1]=>'email')
            $arrCampo = array_keys($values);
            // pegar valores da array
            // ([0]=>'Jose',[1]=>'jose@email.com')
            $arrDados  = array_values($values);
            // contar campos da array
            $numCampo = count($arrCampo);
            // contar dados da array
            $numDados = count($arrDados);

         // Verifica se o parametro $date_insertion foi inicializado
         if(strlen($date_insertion)){

            array_push($arrCampo, $date_insertion);
            array_push($arrDados, "NOW()");
        }

            if($numCampo == $numDados){

   // Criara uma string pata o insert: INSERT INTO contatos (nome, email) VALUES ($_POST['nome'], $_POST['email'])
   //                                  INSERT INTO contatos ( $arrCampo ) VALUES (          $arrValores          )
                $SQL = "INSERT INTO ".$tabela." (";
                foreach ($arrCampo as $campo){ // $campo assume os valores de arrCampo
                    $SQL .= "$campo, ";          // o foreach faz com que se repita N vezes $campo
                }
                    $SQL = substr_replace($SQL, ")", -2, 1);
                    $SQL .= " VALUES (";
                foreach ($arrDados as $valores){
                    $this->anti_sql_injection($valores);
                     if($valores == 'NOW()') // Se for inserir a clausula NOW() nao inclui as aspas simples
                        $SQL .= $valores.", ";
                    else
                        $SQL .= "'".$valores."', ";
                }
                $SQL = substr_replace($SQL, ")", -2, 1);
            }
            else{
               return false;
            }

            $this->select($SQL);

            return true;

        }

        // METODOS PARA ATUALIZACAO DE DADOS

        /**
         * Método para atualização segura dos dados em um banco
         * @abstract Permite atualização dos dados do banco
         * @name update
         * @access public
         * @return bool
         *
         * @param string $tabela Nome da tabela onde os dados serao gravado
         * @param array $values Array contendo os dados a serem cadastrado no banco.
         * @param string $where string contendo as clausulas MYSQL para restição. Ex: (Ex: " WHERE id = $id) .
         * <b>Obs.: </b> O nome no banco deve ser igual ao da variavel no formulario.
         * <br> Exemplo: crie o array da seguinte forma:
         * <br> array('nome' => $nome, 'email' => $_POST['email'])
         */
        public function update($tabela, $values, $where){

            // pegar campos da array
            $arrValores = array_keys($values);
            // pegar valores da array
            $arrCampo = array_values($values);
            // contar campos da array
            $numCampo = count($arrCampo);
            // contar valores da array
            $numValores = count($arrValores);



             //validacao dos campos
            if($numCampo == $numValores && $numValores > 0){
                $SQLUPDATE = "UPDATE ".$tabela." SET ";
                for ($i = 0; $i < $numCampo; ++$i) {
                    $this->anti_sql_injection($arrCampo[$i]);
                    $SQLUPDATE .= $arrValores[$i]." = '".$arrCampo[$i]."',";
                }
                 $SQLUPDATE = substr_replace($SQLUPDATE, " ", -1, 1);
                 $SQLUPDATE .= " $where";
            }
            else{
                return false;
            }
            $this->select($SQLUPDATE);
            return true;
        }

        // METODO DE EXCLUSAO DE DADOS

        /**
         * Metodo deletar dados de um banco
         *
         * @name delete_mysql
         * @access public
         * @return void
         *
         * @param string $tabela Nome da tabela onde os dados serao gravado
         * @param string $where string contendo as clausulas MYSQL para exclusao. (Ex: 'WHERE $id = id).
         */
        public function delete_mysql($tabela, $where){

             $SQL = 'DELETE FROM '.$tabela.' '.$where;
             $this->select($SQL);
        }


    }// end class

?>